import datetime
import logging
import pymongo
import json

from base.request import ApiBaseHandler
from base.connection import mongodb_util
from common.definition import ret_msg
from decimal import Decimal
from conf import config
from helper.api_helper import ApiHelper
from helper.payment.pay_util import generator_trade_no
from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client

logger = logging.getLogger("wechat.handlers.activities")


class AddActivity(ApiBaseHandler):
    def is_num(self, num):
        """判断是否是数字"""
        try:
            Decimal(num)
            return True
        except Exception:
            return False

    async def post(self):
        open_id = await self.get_open_id()
        title = self.get_argument("title", None)
        content = self.get_argument("content", None)
        date_time = self.get_argument("date_time", None)
        nums = self.get_argument("nums", None)
        address = self.get_argument("address", None)
        wine = self.get_argument("wine", "")
        fee = self.get_argument("fee", None)
        remark = self.get_argument("remark", "")
        imgfile = self.request.files.get("img", None)
        if not all([title, content, date_time, nums, address]):
            return self.write(ret_msg(code=-1, error_message="请求参数错误!"))
        if fee is None:
            return self.write(ret_msg(code=-1, error_message="请求参数错误!"))
        flag = self.is_num(fee)
        if not flag:
            return self.write(ret_msg(code=-1, error_message="金额只能是数字"))
        urls = []
        if imgfile:
            secret_id = config.COS_APP_SECRET_ID
            secret_key = config.COS_APP_SECRET_KEY
            region = "ap-guangzhou"
            token = ''
            scheme = "https"
            cfg = CosConfig(Region=region, Secret_id=secret_id, Secret_key=secret_key, Token=token, Scheme=scheme)
            client = CosS3Client(cfg)
            base_url = "https://" + "style-1251902022." + "file.myqcloud.com/static/img/activities/"
            for img in imgfile:
                filename = generator_trade_no() + "_" + img['filename']
                response = client.put_object(
                    Bucket=config.COS_BUCKET + "-" + config.COS_APP_ID,
                    Body=img['body'],
                    Key="static/img/activities/" + filename
                )
                url = base_url + filename
                urls.append(url)
            logger.debug(response)
        logger.debug(urls)

        class User(object):
            pass

        session = self.get_db_session([
            {"db_table": "ebt_user", "model": User}
        ])
        user = session.query(User).filter_by(ebf_user_id=open_id).first()
        if not user:
            return self.write(ret_msg(code=-1, error_message="发布人不存在"))
        headurl = user.ebf_user_headurl
        nickname = user.ebf_user_nickname
        participants = []
        participant = dict(
            open_id=open_id,
            headurl=headurl,
            nickname=nickname
        )
        participants.append(participant)
        data = dict(
            title=title,  # 标题
            content=content,  # 正文
            date_time=date_time,  # 聚餐时间
            nums=nums,  # 人数
            address=address,  # 地址
            wine=wine,  # 酒
            fee=fee,  # 每人费用
            remark=remark,  # 备注
            urls=json.dumps(urls),  # 图片列表
            is_delete=0,  # 0=未删除, 1=已删除
            create_time=datetime.datetime.now(),  # 创建时间
            update_time=datetime.datetime.now(),  # 修改时间
            status=1,  # 饭局状态: 1=进行中, 2=已完成
            open_id=open_id,  # 发布人
            headurl=headurl,  # 发布人头像地址
            nickname=nickname,  # 发布人昵称
            activity_id=generator_trade_no(),  # 饭局唯一标识
            participants=participants  # 参与人及其头像地址列表
        )
        try:
            db = mongodb_util.db
            db.sdec_activities.insert(data)
        except Exception as e:
            logger.error(e)
            return self.write(ret_msg(code=-1, error_message="饭局发布失败, 请稍后重试"))
        return self.write(ret_msg())


class Activities(ApiBaseHandler):
    def dict_activity(self, activity):
        at = dict(
            title=activity["title"],
            content=activity["content"],
            fee=activity["fee"],
            urls=json.loads(activity["urls"]),
            create_time=activity["create_time"].strftime("%Y.%m.%d %H:%M:%S"),
            status=activity["status"],
            open_id=activity["open_id"],
            headurl=activity["headurl"],
            activity_id=activity["activity_id"],
            nickname=activity["nickname"]
        )
        return at

    async def get(self):
        open_id = await self.get_open_id()
        type = self.get_argument("type", "new")  # new=最近发起, old=查看以往, 15天以内为"最近"
        base_num = 15  # "最近"与"以往"判断标准
        page_index = int(self.get_argument("page_index", 0))
        page_size = int(self.get_argument("page_size", 10))
        ApiHelper.inspect_common_params(page_index, page_size)
        page_start = page_index * page_size
        now = datetime.datetime.now()
        base_date = (now + datetime.timedelta(days=-base_num)).replace(hour=0, minute=0, second=0, microsecond=0)
        activities = []
        try:
            db = mongodb_util.db
            if type == "new":
                result = db.sdec_activities.find({
                    "open_id": open_id,
                    "is_delete": 0,
                    "create_time": {"$gte": base_date},
                })
            elif type == "old":
                result = db.sdec_activities.find({
                    "open_id": open_id,
                    "is_delete": 0,
                    "create_time": {"$lt": base_date},
                })
            else:
                return self.write(ret_msg(code=-1, error_message="请求参数错误!"))
            result = result.sort("activity_id", pymongo.DESCENDING).skip(page_start).limit(page_size)
            for activity in result:
                at = self.dict_activity(activity)
                activities.append(at)
        except Exception as e:
            logger.error(e)
            return self.write(ret_msg(code=-1, error_message="查询失败, 请稍后重试"))
        return self.write(ret_msg(data=activities))


class ActivityDetail(ApiBaseHandler):
    def get_week_day(self, date):
        """
        获取指定的日期是星期几
        :param date:
        :return:
        """
        week_day_dict = {
            0: '星期一',
            1: '星期二',
            2: '星期三',
            3: '星期四',
            4: '星期五',
            5: '星期六',
            6: '星期天'
        }
        day = date.weekday()
        return week_day_dict[day]

    def create_comment(self, activity_id, headurl, nickname, open_id, content, parent_id="none", relative_id="none"):
        is_release = "false"
        data = dict(
            comment_id="c" + generator_trade_no(),
            parent_id=parent_id,
            activity_id=activity_id,
            is_delete=0,
            headurl=headurl,
            nickname=nickname,
            open_id=open_id,
            nice=json.dumps([]),
            create_time=datetime.datetime.now(),
            update_time=datetime.datetime.now()
        )
        try:
            db = mongodb_util.db
            result = db.sdec_activities.find_one({"activity_id": activity_id, "is_delete": 0})
            if open_id == result["open_id"] and parent_id == "none":
                is_release = "ture"

            if parent_id == "none":
                data["is_release"] = is_release
                data["content"] = content
                data["relative_id"] = relative_id
            else:
                c = db.sdec_comments.find_one({"comment_id": parent_id})
                if relative_id != "none":
                    relative_comment = db.sdec_comments.find_one({"comment_id": relative_id})
                else:
                    data["relative_id"] = parent_id
                    relative_comment = None

                if not c:
                    raise Exception("评论不存在!")
                if relative_comment and relative_comment["open_id"] != open_id:
                    full_content = dict(
                        pre_content=nickname + "回复" + relative_comment["nickname"],
                        suf_content=content
                    )
                    data["content"] = full_content
                else:
                    full_content = dict(
                        pre_content=nickname,
                        suf_content=content
                    )
                    data["content"] = full_content
            db.sdec_comments.insert(data)
        except Exception as e:
            logger.error(e)
            return False
        return True

    async def get(self):
        activity_id = self.get_argument("activity_id", None)
        page_index = int(self.get_argument("page_index", 0))
        page_size = int(self.get_argument("page_size", 10))
        ApiHelper.inspect_common_params(page_index, page_size)
        page_start = page_index * page_size
        open_id = await self.get_open_id()
        if not activity_id:
            return self.write(ret_msg(code=-1, error_message="请求参数错误!"))
        try:
            db = mongodb_util.db
            activity = db.sdec_activities.find_one({"activity_id": activity_id, "is_delete": 0})
            if not activity:
                return self.write(ret_msg(code=-1, error_message="查询的饭局不存在!"))
            at = dict(
                title=activity["title"],
                fee=activity["fee"],
                urls=json.loads(activity["urls"]),
                create_time=activity["create_time"].strftime("%m月%d日 %H:%M"),
                status=activity["status"],
                open_id=activity["open_id"],
                headurl=activity["headurl"],
                activity_id=activity["activity_id"],
                nickname=activity["nickname"],
                date_time=activity["date_time"],
                nums=activity["nums"],
                address=activity["address"],
                remark=activity["remark"],
                participants=activity["participants"]
            )
            result = db.sdec_comments.find({
                "activity_id": activity_id,
                "is_delete": 0,
                "parent_id": "none"
            })
            result = result.sort("create_time", pymongo.DESCENDING).skip(page_start).limit(page_size)
            comments = []
            for c in result:
                nice = json.loads(c["nice"])
                if open_id in nice:
                    is_nice = "true"
                else:
                    is_nice = "false"
                comment = dict(
                    parent_id=c["comment_id"],
                    parent_headurl=c["headurl"],
                    parent_nickname=c["nickname"],
                    parent_open_id=c["open_id"],
                    is_release=c["is_release"],
                    parent_content=c["content"],
                    create_time=c["create_time"].strftime("%m月%d日 %H:%M"),
                    is_nice=is_nice
                )
                r = db.sdec_comments.find({
                    "activity_id": activity_id,
                    "is_delete": 0,
                    "parent_id": c["comment_id"],
                    "relative_id": {"$ne": "none"}
                }).sort("create_time", pymongo.DESCENDING)
                children_comment = []
                for child_c in r:
                    chlid_comment = dict(
                        child_id=child_c["comment_id"],
                        child_content=child_c["content"],
                        child_open_id=child_c["open_id"],
                        child_nickname=child_c["nickname"]
                    )
                    children_comment.append(chlid_comment)
                comment["children_comment"] = children_comment
                comments.append(comment)
            context = dict(
                activity=at,
                comments=comments
            )
        except Exception as e:
            logger.error(e)
            return self.write(ret_msg(code=-1, error_message="查询失败, 请稍后重试!"))
        return self.write(ret_msg(data=context))

    async def post(self):
        open_id = await self.get_open_id()
        action = self.get_parameter("action", None)
        activity_id = self.get_parameter("activity_id", None)

        class User(object):
            pass

        session = self.get_db_session([
            {"db_table": "ebt_user", "model": User}
        ])
        user = session.query(User).filter_by(ebf_user_id=open_id).first()
        if not user:
            return self.write(ret_msg(code=-1, error_message="评论人不存在"))
        headurl = user.ebf_user_headurl
        nickname = user.ebf_user_nickname
        if action == "comment":  # 评论
            if not activity_id:
                logger.error("没有activity_id")
                return self.write(ret_msg(code=-1, error_message="请求参数错误!"))
            content = self.get_parameter("content", None)
            if not content:
                return self.write(ret_msg(code=-1, error_message="评论内容不能为空!"))
            parent_id = "none"
            result = self.create_comment(activity_id, headurl, nickname, open_id, content, parent_id)
            if not result:
                return self.write(ret_msg(code=-1, error_message="评论发布失败, 请稍后重试!"))
            return self.write(ret_msg())
        elif action == "reply":  # 回复
            parent_id = self.get_parameter("parent_id", None)  # 一级评论
            relative_id = self.get_parameter("relative_id", None)  # 相对回复的评论id
            content = self.get_parameter("content", None)
            if not parent_id:
                logger.error("parent_id为空")
                return self.write(ret_msg(code=-1, error_message="请求参数错误!"))

            if not content:
                return self.write(ret_msg(code=-1, error_message="评论内容不能为空!"))
            logger.debug("relative_id=%s, parent_id=%s" % (relative_id, parent_id))
            result = self.create_comment(activity_id, headurl, nickname, open_id, content, parent_id, relative_id)
            if not result:
                return self.write(ret_msg(code=-1, error_message="评论发布失败, 请稍后重试!"))
            return self.write(ret_msg())
        elif action == "nice":  # 点赞
            comment_id = self.get_parameter("comment_id", None)
            if not activity_id:
                logger.error("没有activity_id")
                return self.write(ret_msg(code=-1, error_message="请求参数错误!"))
            if not comment_id:
                logger.error("comment_id为空")
                return self.write(ret_msg(code=-1, error_message="请求参数错误!"))
            try:
                db = mongodb_util.db
                _filter = {"comment_id": comment_id, "is_delete": 0}
                result = db.sdec_comments.find_one(_filter)
                if not result:
                    return self.write(ret_msg(code=-1, error_message="评论不存在,点赞失败!"))
                nice = json.loads(result["nice"])
                nice.append(open_id)
                nice = list(set(nice))
                nice = json.dumps(nice)
                logger.debug("nice=%s" % nice)
                db.sdec_comments.update({"comment_id": comment_id, "is_delete": 0}, {"$set": {"nice": nice}})
            except Exception as e:
                logger.error(e)
                return self.write(ret_msg(code=-1, error_message="系统繁忙, 请稍后重试!"))
            return self.write(ret_msg())
        else:
            return self.write(ret_msg(code=-1, error_message="无效的请求!"))
